﻿using CSRedis;
using IM.Easy.Api.Filters;
using IM.Easy.Api.Hubs;
using IM.Easy.Api.Options;
using IM.Easy.Core.AppContext;
using IM.Easy.Core.Cache;
using IM.Easy.Core.Configuration;
using IM.Easy.Core.Filters;
using IM.Easy.Core.JsonConverter;
using IM.Easy.Core.Log;
using IM.Easy.Core.Middleware;
using IM.Easy.Core.Options;
using IM.Easy.Core.Route;
using IM.Easy.Core.ServiceLifetime;
using IM.Easy.Core.Services;
using Mapster;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyModel;
using Microsoft.IdentityModel.Tokens;
using SqlSugar;
using System.Reflection;
using System.Text;
using IM.Easy.Api.OAuth;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.Options;
using IM.Easy.Core.OAuth;
using IM.Easy.Api.Options.OAuth;
using IM.Easy.Core.OAuth.Providers;
using AMapPlugin;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Quartz;
using Quartz.Spi;
using IM.Easy.ScheduledServices.Dtos;
using IM.Easy.ScheduledServices.IServices;
using IM.Easy.Api.HostedService;
using IM.Easy.ScheduledServices.Jobs;
using IM.Easy.ScheduledServices.Listener;
using GiteePlugin.Core.Extensions;
using AIPlugin.Core.Extensions;
using AIPlugin.Configuration;
using IM.Easy.ScheduledServices.Services;

namespace IM.Easy.Api.Extensions
{
    public static class ServicesExtensions
    {
        public static void RegisterServices(this IServiceCollection serviceCollection)
        {
            var assemblies = new List<Assembly>();
            // 创建一个服务描述符集合
            var serviceDescriptors = new List<ServiceDescriptor>();

            //// 获取所有程序集（可以指定只获取当前应用的程序集）
            //var assemblies = AppDomain.CurrentDomain.GetAssemblies();

            // 通过 DependencyContext 获取当前项目和引用项目的所有依赖程序集
            var dependencies = DependencyContext.Default.RuntimeLibraries;
            foreach (var library in dependencies)
            {
                // 加载引用的外部程序集
                if (library.Type == "project" || library.Type == "assembly")
                {
                    try
                    {
                        assemblies.Add(Assembly.Load(new AssemblyName(library.Name)));
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"无法加载程序集 {library.Name}: {ex.Message}");
                    }
                }
            }

            // 获取所有服务类型
            var serviceTypes = assemblies.SelectMany(a => a.GetTypes())
                .Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface && (typeof(IScoped).IsAssignableFrom(t) || typeof(ITransient).IsAssignableFrom(t) || typeof(ISingleton).IsAssignableFrom(t)))
                .ToList();

            foreach (var serviceType in serviceTypes)
            {
                // 根据接口的实现类型注册服务
                var lifetime = GetServiceLifetime(serviceType);

                var @interface = serviceType.GetInterfaces().ToList().FirstOrDefault(s => s.Name.EndsWith(serviceType.Name));
                var type = @interface ?? serviceType;
                serviceDescriptors.Add(new ServiceDescriptor(type, serviceType, lifetime));
            }

            // 将服务描述符添加到服务集合
            foreach (var descriptor in serviceDescriptors)
            {
                serviceCollection.Add(descriptor);
            }
        }

        // 获取服务生命周期
        private static ServiceLifetime GetServiceLifetime(Type serviceType)
        {
            if (typeof(IScoped).IsAssignableFrom(serviceType))
            {
                return ServiceLifetime.Scoped;
            }
            if (typeof(ITransient).IsAssignableFrom(serviceType))
            {
                return ServiceLifetime.Transient;
            }
            if (typeof(ISingleton).IsAssignableFrom(serviceType))
            {
                return ServiceLifetime.Singleton;
            }
            return ServiceLifetime.Scoped; // 默认生命周期
        }

        /// <summary>
        /// 动态路由
        /// </summary>
        public static IServiceCollection UseDynamicRoute(this IServiceCollection services)
        {
            services.AddControllers(options =>
            {
                options.Conventions.Add(new ImRouteConvention());
                //options.Filters.Add<GlobalAuthorizeFilter>();
                options.Filters.Add<EndpointAuthorizationFilter>();
                options.Filters.Add<PermissionFilter>();
                options.Filters.Add<DemoFilter>();      //演示模式控制
                options.Filters.Add<ValidateModelStateFilter>();
                options.Filters.Add<GlobalLoggerFilter>(int.MinValue);
                options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true;
                //options.Filters.Add(new ValidateModelAttribute());
            }).AddJsonOptions(options =>
            {
                options.JsonSerializerOptions.Converters.Add(new BoolConverter());
                options.JsonSerializerOptions.Converters.Add(new Int32Converter());
                options.JsonSerializerOptions.Converters.Add(new LongStringConverter());
                // 添加其他配置（如日期格式）如果需要
            }); ;


            return services;
        }

        public static IServiceCollection UseUnifiedResult(this IServiceCollection services)
        {
            services.AddControllers(options =>
            {
                options.Filters.Add<ApiActionFilter>();
                options.Filters.Add<ApiResultFilter>();
                //options.Filters.Add<ApiExceptionFilter>();
            });
            return services;
        }

        public static IServiceCollection ConfigureSettings(this IServiceCollection serviceDescriptors, IConfiguration configuration)
        {
            //ConfigManager.Initialize(configuration);
            //ConfigManager.Configure(configuration);
            return serviceDescriptors;
        }

        public static IServiceCollection RegisteMapping(this IServiceCollection serviceDescriptors)
        {
            var assemblies = AppDomain.CurrentDomain.GetAssemblies();
            var config = TypeAdapterConfig.GlobalSettings;
            config.Scan(assemblies);
            serviceDescriptors.AddSingleton(config);
            return serviceDescriptors;
        }

        /// <summary>
        /// 框架核心服务
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AppCoreSetup(this IServiceCollection services)
        {
            var connection = ImApp.Configuration.Get<CacheConnection>();
            CacheManager.Initialize(connection);

            return services;
        }

        /// <summary>
        /// 添加Jwt认证
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddImAuthentication(this IServiceCollection services)
        {


            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddDefaultAuthentication();
            //.AddGiteeAuthentication();
            // 添加授权服务
            services.AddAuthorization();
            return services;
        }

        /// <summary>
        /// 添加实时通信组件
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddImSignalR(this IServiceCollection services)
        {
            //services.AddSingleton<IUserIdProvider, UserIdProvider>();
            services.AddSignalR();
            return services;
        }

        /// <summary>
        /// 引入三方登录提供商
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddOAuthProvider(this IServiceCollection services)
        {
            var giteeOptions = ImApp.Configuration.Get<GiteeAuthOptions>();
            services.AddOAuthBuilder()
                .AddGiteeProvider()
                .Build();
            //.AddGiteeProvider(opt =>
            //{
            //    opt.ClientId = giteeOptions.ClientId;
            //    opt.ClientSecret = giteeOptions.ClientSecret;
            //}).Build();
            //var serviceProvider = services.BuildServiceProvider();
            //var oAuthProviderFactory = serviceProvider.GetRequiredService<OAuthProviderFactory>();
            //// 创建实例
            //var authProvider = oAuthProviderFactory.Create("Gitee");
            return services;
        }

        public static IServiceCollection AddImWorkFlow(this IServiceCollection services)
        {
            services.AddHostedService<WorkflowInitService>();
            var configs = ImApp.Configuration.Get<DbConnection>();
            var connection = configs.ConnectionConfigs.FirstOrDefault(s => s.ConfigId.ToString() == "Workflow");
            services.AddWorkflow(cfg =>
            {
                cfg.UseMySQL(connection.ConnectionString, true, true);
            });
            return services;
        }

        /// <summary>
        /// 添加任务调度计划
        /// </summary>
        /// <returns></returns>
        public static IServiceCollection AddScheduledTask(this IServiceCollection services)
        {
            // 注册 Quartz 
            services.AddScoped<RemoteJob>();
            services.AddQuartz(q =>
            {
                q.UsePersistentStore(store =>
                {
                    store.UseSQLite("Data Source=./quartz.db;Version=3;");
                    store.UseSystemTextJsonSerializer();
                });

                //添加日志监听器
                q.AddSchedulerListener<SchedulerListener>();
                q.AddJobListener<JobListener>();
            });
            services.AddQuartzHostedService(opt =>
            {
                opt.WaitForJobsToComplete = true;
            });

            services.AddSingleton(sp =>
            {
                var factory = sp.GetRequiredService<ISchedulerFactory>();
                return factory.GetScheduler().GetAwaiter().GetResult();
            });

            services.AddSingleton<ISchedulerService, SchedulerService>();

            return services;
        }

        #region add Plugins
        public static IServiceCollection AddPlugins(this IServiceCollection services)
        {
            var key = ImApp.Configuration.GetConfigurationValue("AmapKey");
            services.AddAmapPlugin(opt =>
            {
                opt.Key = key;
            });

            //添加gitee插件
            services.AddGiteePlugin(opt =>
            {

            });
            var aiOption = ImApp.Configuration.GetSection<ChatOptions>("AIAuth");
            //引入AI插件
            services.AddAIPlugin(opt =>
            {
                opt.Endpoint = aiOption.Endpoint;
                opt.Secret = aiOption.Secret;
                opt.Model = aiOption.Model;
            });
            return services;
        }
        #endregion
    }
}
